#include<pthread.h>
#include<queue>
#include<iostream>
#include"mutex.hpp"
#include"cond.hpp"

namespace blockqueuemoduer
{
    using namespace condmodule;
    using namespace mutexmodule;
    template<class T>
    class blockqueue
    {
    private:
        bool isfull(){return data_queue.size()==cap;}
        bool isempty(){return data_queue.size()==0;}
    public:
        blockqueue():cap(5),pro_wait_num(0),com_wait_num(0)
        {
        }
        void pop(T* data)
        {
            lockgroud lockgroud(mutex);
            while(isempty())
            {
                std::cout<<"数据空了,消费者停止消费"<<std::endl;
                com_wait_num++;
                c_cond.wait(mutex.addr());
                com_wait_num--;
                std::cout<<"消费者被唤醒"<<std::endl;
            }
            *data=data_queue.front();
            data_queue.pop();
            if(pro_wait_num)
            {
                p_cond.Nodify();
                std::cout<<"唤醒一个生产者"<<std::endl;
            }
        }
        void enterqueue(const T& data)
        {
            lockgroud lockgroud(mutex);
            //生产者线程进行生产
            while(isfull())
            {
                std::cout<<"数据满了，生产者停止生产"<<std::endl;
                pro_wait_num++;
                p_cond.wait(mutex.addr());
                pro_wait_num--;
                std::cout<<"生产者继续生产"<<std::endl;
            }
            // 数据未满||消费者还没有陷入等待          
            data_queue.push(data);
            if(com_wait_num)//唤醒消费者
            {
                std::cout<<"唤醒了一个消费者线程"<<std::endl;
                c_cond.Nodify();
            }
        }
        ~blockqueue()
        {
        }
    private:
        std::queue<T> data_queue;//数据存放在队列中
        int cap;//最大容量
        mutexmodule::mutex mutex;//互斥锁
        cond c_cond;//消费者条件变量
        cond p_cond;//生产者的条件
        int com_wait_num;//等待的消费者数量
        int pro_wait_num;//等待的生产者数量
    };

    // template<class T>
    // class blockqueue
    // {
    // private:
    //     bool isfull(){return data_queue.size()==cap;}
    //     bool isempty(){return data_queue.size()==0;}
    // public:
    //     blockqueue():cap(5),pro_wait_num(0),com_wait_num(0)
    //     {
    //         pthread_mutex_init(&mutex,nullptr);
    //         pthread_cond_init(&c_cond,nullptr);
    //         pthread_cond_init(&p_cond,nullptr);
    //     }
    //     void pop()
    //     {
    //         pthread_mutex_lock(&mutex);
    //         if(isempty())
    //         {
    //             std::cout<<"数据空了,消费者停止消费"<<std::endl;
    //             com_wait_num++;
    //             pthread_cond_wait(&c_cond,&mutex);
    //             com_wait_num--;
    //             std::cout<<"消费者被唤醒"<<std::endl;
    //         }
    //         std::cout<<"消费者拿到数据:"<<data_queue.front()<<std::endl;
    //         data_queue.pop();
    //         if(pro_wait_num)
    //         {
    //             pthread_cond_signal(&p_cond);
    //             std::cout<<"唤醒一个生产者"<<std::endl;
    //         }
    //         pthread_mutex_unlock(&mutex);
    //     }
    //     void enterqueue(const T&data)
    //     {
    //         pthread_mutex_lock(&mutex);  
    //         //生产者线程进行生产
    //         if(isfull())
    //         {
    //             std::cout<<"数据满了，生产者停止生产"<<std::endl;
    //             pro_wait_num++;
    //             pthread_cond_wait(&p_cond,&mutex);
    //             pro_wait_num--;
    //             std::cout<<"生产者继续生产"<<std::endl;
    //         }
    //         // 数据未满||消费者还没有陷入等待          
    //         data_queue.push(data);
    //         if(com_wait_num)//唤醒消费者
    //         {
    //             std::cout<<"唤醒了一个消费者线程"<<std::endl;
    //             pthread_cond_signal(&c_cond);
    //         }
    //         pthread_mutex_unlock(&mutex);
    //     }
    //     ~blockqueue()
    //     {
    //         pthread_mutex_destroy(&mutex);
    //         pthread_cond_destroy(&c_cond);
    //         pthread_cond_destroy(&p_cond);
    //     }
    // private:
    //     std::queue<T> data_queue;//数据存放在队列中
    //     int cap;//最大容量
    //     pthread_mutex_t mutex;//互斥锁
    //     pthread_cond_t c_cond;//消费者条件变量
    //     pthread_cond_t p_cond;//生产者的条件
    //     int com_wait_num;//等待的消费者数量
    //     int pro_wait_num;//等待的生产者数量
    // };
}